//  代码地址: https://github.com/CoderMJLee/RCMJRefresh
//  代码地址:
//  http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
//  RCMJRefreshComponent.m
//  RCMJRefreshExample
//
//  Created by MJ Lee on 15/3/4.
//  Copyright (c) 2015年 小码哥. All rights reserved.
//

#import "RCMJRefreshComponent.h"
#import "RCMJRefreshConst.h"

@interface RCMJRefreshComponent ()
@property (strong, nonatomic) UIPanGestureRecognizer *pan;
@end

@implementation RCMJRefreshComponent
#pragma mark - 初始化
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 准备工作
        [self prepare];

        // 默认是普通状态
        self.state = RCMJRefreshStateIdle;
    }
    return self;
}

- (void)prepare {
    // 基本属性
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.backgroundColor = [UIColor clearColor];
}

- (void)layoutSubviews {
    [self placeSubviews];

    [super layoutSubviews];
}

- (void)placeSubviews {
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];

    // 如果不是UIScrollView，不做任何事情
    if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]])
        return;

    // 旧的父控件移除监听
    [self removeObservers];

    if (newSuperview) { // 新的父控件
        // 记录UIScrollView
        _scrollView = (UIScrollView *)newSuperview;

        // 设置宽度
        self.rcmj_w = _scrollView.rcmj_w;
        // 设置位置
        self.rcmj_x = -_scrollView.rcmj_insetL;

        // 设置永远支持垂直弹簧效果
        _scrollView.alwaysBounceVertical = YES;
        // 记录UIScrollView最开始的contentInset
        _scrollViewOriginalInset = _scrollView.rcmj_inset;

        // 添加监听
        [self addObservers];
    }
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    if (self.state == RCMJRefreshStateWillRefresh) {
        // 预防view还没显示出来就调用了beginRefreshing
        self.state = RCMJRefreshStateRefreshing;
    }
}

#pragma mark - KVO监听
- (void)addObservers {
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.scrollView addObserver:self forKeyPath:RCMJRefreshKeyPathContentOffset options:options context:nil];
    [self.scrollView addObserver:self forKeyPath:RCMJRefreshKeyPathContentSize options:options context:nil];
    self.pan = self.scrollView.panGestureRecognizer;
    [self.pan addObserver:self forKeyPath:RCMJRefreshKeyPathPanState options:options context:nil];
}

- (void)removeObservers {
    [self.superview removeObserver:self forKeyPath:RCMJRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:RCMJRefreshKeyPathContentSize];
    [self.pan removeObserver:self forKeyPath:RCMJRefreshKeyPathPanState];
    self.pan = nil;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
    // 遇到这些情况就直接返回
    if (!self.userInteractionEnabled)
        return;

    // 这个就算看不见也需要处理
    if ([keyPath isEqualToString:RCMJRefreshKeyPathContentSize]) {
        [self scrollViewContentSizeDidChange:change];
    }

    // 看不见
    if (self.hidden)
        return;
    if ([keyPath isEqualToString:RCMJRefreshKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    } else if ([keyPath isEqualToString:RCMJRefreshKeyPathPanState]) {
        [self scrollViewPanStateDidChange:change];
    }
}

- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {
}
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change {
}
- (void)scrollViewPanStateDidChange:(NSDictionary *)change {
}

#pragma mark - 公共方法
#pragma mark 设置回调对象和回调方法
- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action {
    self.refreshingTarget = target;
    self.refreshingAction = action;
}

- (void)setState:(RCMJRefreshState)state {
    _state = state;

    // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件
    RCMJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];)
}

#pragma mark 进入刷新状态
- (void)beginRefreshing {
    [UIView animateWithDuration:RCMJRefreshFastAnimationDuration
                     animations:^{
                         self.alpha = 1.0;
                     }];
    self.pullingPercent = 1.0;
    // 只要正在刷新，就完全显示
    if (self.window) {
        self.state = RCMJRefreshStateRefreshing;
    } else {
        // 预防正在刷新中时，调用本方法使得header inset回置失败
        if (self.state != RCMJRefreshStateRefreshing) {
            self.state = RCMJRefreshStateWillRefresh;
            // 刷新(预防从另一个控制器回到这个控制器的情况，回来要重新刷新一下)
            [self setNeedsDisplay];
        }
    }
}

- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock {
    self.beginRefreshingCompletionBlock = completionBlock;

    [self beginRefreshing];
}

#pragma mark 结束刷新状态
- (void)endRefreshing {
    RCMJRefreshDispatchAsyncOnMainQueue(self.state = RCMJRefreshStateIdle;)
}

- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock {
    self.endRefreshingCompletionBlock = completionBlock;

    [self endRefreshing];
}

#pragma mark 是否正在刷新
- (BOOL)isRefreshing {
    return self.state == RCMJRefreshStateRefreshing || self.state == RCMJRefreshStateWillRefresh;
}

#pragma mark 自动切换透明度
- (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha {
    self.automaticallyChangeAlpha = autoChangeAlpha;
}

- (BOOL)isAutoChangeAlpha {
    return self.isAutomaticallyChangeAlpha;
}

- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha {
    _automaticallyChangeAlpha = automaticallyChangeAlpha;

    if (self.isRefreshing)
        return;

    if (automaticallyChangeAlpha) {
        self.alpha = self.pullingPercent;
    } else {
        self.alpha = 1.0;
    }
}

#pragma mark 根据拖拽进度设置透明度
- (void)setPullingPercent:(CGFloat)pullingPercent {
    _pullingPercent = pullingPercent;

    if (self.isRefreshing)
        return;

    if (self.isAutomaticallyChangeAlpha) {
        self.alpha = pullingPercent;
    }
}

#pragma mark - 内部方法
- (void)executeRefreshingCallback {
    RCMJRefreshDispatchAsyncOnMainQueue({
        if (self.refreshingBlock) {
            self.refreshingBlock();
        }
        if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
            RCMJRefreshMsgSend(RCMJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self);
        }
        if (self.beginRefreshingCompletionBlock) {
            self.beginRefreshingCompletionBlock();
        }
    })
}
@end

@implementation UILabel (RCMJRefresh)
+ (instancetype)rcmj_label {
    UILabel *label = [[self alloc] init];
    label.font = RCMJRefreshLabelFont;
    label.textColor = RCMJRefreshLabelTextColor;
    label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    return label;
}

- (CGFloat)rcmj_textWidth {
    CGFloat stringWidth = 0;
    CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT);
    if (self.text.length > 0) {
        stringWidth = [self.text boundingRectWithSize:size
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                               NSFontAttributeName : self.font
                                           }
                                              context:nil]
                          .size.width;
    }
    return stringWidth;
}
@end
